<html>
  <head>
    <title>Scriv2DocBook - a simple workflow for developing DocBook in Scrivener</title>
    <link href="http://fonts.googleapis.com/css?family=Inconsolata|Cabin:400,600,400italic,600italic" rel="stylesheet" type="text/css" />
    <style>
.innerbox {
    margin: 0 auto;
    max-width: 800px;
    font-family: "Cabin", sans-serif;
    line-height: 140%;

    color: #333;
}

h1, h2, h3, h4, h5, h6 {
    font-family: "Cabin", sans-serif;
    line-height: 140%;
}

h2 {
    border-top: 1px solid #ccc;
    padding-top: 10px;
    margin-top: 40px;
}

pre, code {
    font-family: "Inconsolata", sans-serif;
}

pre {
    margin-left: 1em;
    padding-left: 1em;
    border-left: 3px solid #ccc;
}

td {
    padding: 0 1em;
}
    </style>
  </head>
  <body><div class="innerbox">

    <h1 id="Scriv2DocBook">Scriv2DocBook</h1>

    <p>Scriv2DocBook is a simple workflow for writing technical books in <a href="http://www.literatureandlatte.com/scrivener.php">Scrivener</a>, the text composition application from <a href="http://www.literatureandlatte.com/">Literature &amp; Latte</a>.  The end result is DocBook XML suitable for delivery to a publisher, or rendering into other formats using DocBook tools.</p>

    <p>Scriv2DocBook consists of:</p>
    <ul>
      <li>a method for composing a technical book as a Scrivener project</li>
      <li>a tool for exporting such a project as DocBook XML</li>
      <li>a tool for importing a subset of DocBook XML back into Scrivener</li>
    </ul>

    <p>The tools are tuned especially for writing for <a href="http://www.oreilly.com/">O&rsquo;Reilly Media</a>, but the result is standard DocBook.</p>

    <p>The Scriv2DocBook conversion tools are free software, released under the Apache License, Version 2.0.</p>

    <h2 id="Contents">Contents</h2>
    <ul>
      <li><a href="#Scriv2DocBook">Scriv2DocBook</a>
        <ul>
          <li><a href="#Contents">Contents</a></li>
          <li><a href="#Caveats">Caveats</a></li>
          <li><a href="#Installing_Scriv2DocBook">Installing Scriv2DocBook</a></li>
          <li><a href="#Setting_Up_Scrivener">Setting Up Scrivener</a></li>
          <li><a href="#Writing_Your_Book">Writing Your Book</a>
            <ul>
              <li><a href="#Chapters_and_Prefaces">Chapters and Prefaces</a></li>
              <li><a href="#Titles_and_Section_IDs">Titles and Section IDs</a></li>
              <li><a href="#Block_Elements">Block Elements</a></li>
              <li><a href="#Block_Elements_Containing_Paragraphs">Block Elements Containing Paragraphs</a></li>
              <li><a href="#Other_Features_of_XML_and_DocBook">Other Features of XML and DocBook</a></li>
            </ul>
          </li>
          <li><a href="#Exporting_DocBook_XML">Exporting DocBook XML</a></li>
          <li><a href="#Importing_a_DocBook_Project_to_Scrivener">Importing a DocBook Project to Scrivener</a></li>
          <li><a href="#License">License</a></li>
        </ul>
      </li>
    </ul>


    <h2 id="Caveats">Caveats</h2>

    <p><strong>Scrivener is not an XML editor.</strong>  I can&rsquo;t stress this enough.  Scriv2DocBook expects you to hand-type XML markup into a Scrivener project.  This is error prone, and even the most experienced XML typist will encounter syntax and validation errors.  You will not catch these errors until you export, and tracing these errors back to their origin in your Scrivener project will be tedious.</p>

    <p>My general recommendation is to <em>not</em> use Scriv2DocBook!  Most people will be happier with an XML editing environment, ideally one that validates to a schema as you type.  <a href="http://www.oxygenxml.com/">Oxygen</a>, <a href="http://www.syntext.com/products/serna/">Syntext Serna</a>, or <a href="http://www.gnu.org/software/emacs/">Emacs</a> with <a href="http://www.thaiopensource.com/nxml-mode/">nxml mode</a> are all good options, and highly recommended over editing XML in an application not suited to that purpose.  Only proceed if you, like me, are overwhelmed by Scrivener&rsquo;s other considerable charms, and are willing to take on this burden.</p>

    <p>I wrote Scriv2DocBook for my own use on a project for <a href="http://www.oreilly.com/">O&rsquo;Reilly Media</a> (<i><a href="http://ae-book.appspot.com/">Programming Google App Engine</a></i>, if you&rsquo;re interested).  These tools are designed and tested around O&rsquo;Reilly&rsquo;s workflow and house style.  Scriv2DocBook is not necessarily suitable for all DocBook projects in all situations.</p>

    <p>Like most home-grown book author tools, Scriv2DocBook represents a way of working that suits me, and it may not suit you.  I present this publicly because people interested in doing something similar have asked me about it.</p>

    <p>Familiarity with DocBook XML and related command-line tools is required.</p>


    <h2 id="Installing_Scriv2DocBook">Installing Scriv2DocBook</h2>

    <p>To use Scriv2DocBook, you need the following:</p>
    <ul>
      <li><a href="http://www.literatureandlatte.com/scrivener.php">Scrivener</a>, version 2 or later.  Importing DocBook requires Scrivener 2.1.1 or later, due to a bug in Scrivener&rsquo;s OPML import that was fixed in this version.</li>
      <li><a href="http://xmlsoft.org/xmllint.html">xmllint</a>, a command-line XML validator tool.  (Mac users, you already have this.)</li>
      <li><a href="http://www.python.org/">Python</a>, version 2.5 or later.  (Mac users, you already have this.)</li>
      <li><a href="http://www.docbook.org/xml/4.4/docbook-xml-4.4.zip">DocBook 4.4 schema files</a> (zip).  (I did not test validation with DocBook 5, and the DocBook 5 schema archive does not include a <code>catalog.xml</code> file for <code>xmllint</code>. Suggestions welcome.)</li>
    </ul>

    <p><a href="http://phbt.googlecode.com/files/scriv2docbook_0.1.zip">Download Scriv2DocBook</a> and unpack the archive.  The archive includes the <code>s2d</code> and <code>d2s</code> commands, which are intended to be run from the unpacked directory.</p>


    <h2 id="Setting_Up_Scrivener">Setting Up Scrivener</h2>

    <p>By default, Scrivener acts as a &ldquo;rich text&rdquo; editor, offering variable-width typefaces and modest formatting capabilities such as bold and italic text.  It also enables automatic assistance with typographic characters (&ldquo;smart quotes&rdquo;) by default.  These features interfere with Scriv2DocBook&rsquo;s purpose, and it&rsquo;s best to turn them off.  You&rsquo;ll also want to use a fixed-width typeface, to make inline XML tags easier to read.</p>

    <ol>
      <li>
        <p>Open the Preferences panel (for Mac, select the <strong>Scrivener</strong> menu, <strong>Preferences...</strong>).  In the Formatting tab, on the tab stop ruler above the sample text, grab the paragraph indent marker (the small rectangle) and drag it all the way to the left, so paragraphs are not indented.</p>
      </li>
      <li>
        <p>Open the font selector (click the &ldquo;A&rdquo; button), then select Courier New, or your favorite fixed-width font family.  Select a typeface and font size, as desired.</p>
        <p><img src="README_images/preferences_formatting.png" /></p>
      </li>
      <li>
        <p>In the Corrections tab, uncheck &ldquo;Use smart quotes,&rdquo; &ldquo;Replace double hyphens with em-dashes,&rdquo; and &ldquo;Replace triple periods with ellipses.&rdquo;  These must be unchecked to prevent accidentally corrupting DocBook XML attributes and computer source code in your text, which must use &ldquo;straight quotes.&rdquo;  O&rsquo;Reilly actually wants typographic characters (such as smart quotes) in DocBook XML source for prose, but O&rsquo;Reilly&rsquo;s tool chain replaces these automatically, and in the appropriate places, when you submit text.</p>
        <p>Uncheck other options, as desired.  Personally, I leave &ldquo;Check spelling as you type in new projects&rdquo; on, and disable everything else.  The goal is to get Scrivener to behave as much like a plain text editor as possible.</p>
        <p><img src="README_images/preferences_corrections.png" /></p>
      </li>
      <li>
        <p>In the Import/Export tab, under OPML, &ldquo;Import notes into,&rdquo; confirm that &ldquo;Main Text (with Synopsis)&rdquo; is selected.  (This is the default.)</p>
        <p><img src="README_images/preferences_import_export.png" /></p>
      </li>
    </ol>

    <p>See also section 21.6 of the Scrivener manual (select the <strong>Help</strong> menu, <strong>Scrivener Manual</strong>), which describes how to do something similar for the purposes of MultiMarkdown (another Scrivener export option).</p>


    <h2 id="Writing_Your_Book">Writing Your Book</h2>

    <p>With Scriv2DocBook, you use Scrivener sections to define the structure of your book.  When you export, the hierarchy of Scrivener sections is converted into a hierarchy of DocBook chapters and sections.</p>

    <p>The content of each section is DocBook XML, with one major exception: paragraphs.  To avoid cluttering the display with <code>&lt;para&gt;</code> tags, Scriv2DocBook recognizes blocks of text separated by a blank line as paragraphs, and adds the <code>&lt;para&gt;</code> tags during export.</p>

    <p><img src="README_images/binder_and_paragraphs.png" /></p>

    <p>Everything else that appears in the text is treated as literal DocBook XML.  Inline elements appear directly within paragraph text.  Block elements can be separated from surrounding paragraphs with blank lines, and otherwise appear as typed in the final XML.</p>

    <p><img src="README_images/block_element.png" /></p>


    <h3 id="Chapters_and_Prefaces">Chapters and Prefaces</h3>

    <p>Top-level Scrivener sections in your draft become chapters.  Each chapter gets a <code>&lt;chapter&gt;</code> element in the XML output.  Inner sections become sub-sections of the chapters, in the hierarchy represented in the Scrivener project; these use <code>&lt;sect<i>#</i>&gt;</code> elements.</p>

    <p>DocBook has a special element for preface chapters: <code>&lt;preface&gt;</code>.  Scriv2DocBook will use the <code>&lt;preface&gt;</code> element only if the chapter title is <code>Preface</code>.  In all other cases, it uses <code>&lt;chapter&gt;</code>.</p>

    <p>Scriv2DocBook only knows how to make prefaces, chapters, and sections.  It does not support &ldquo;parts&rdquo; (the level of hierarchy above chapters).</p>


    <h3 id="Titles_and_Section_IDs">Titles and Section IDs</h3>

    <p>Chapters and sections have titles.  Scriv2DocBook uses the name of the Scrivener section as the title of the chapter or section.</p>

    <p>Chapters and sections also have XML identifiers, which appear in the XML source as <code>id="..."</code> attribtues.  You use these attributes when creating cross references in your text.  Scriv2DocBook generates these IDs automatically based on the section titles.  It does so by replacing all characters that aren&rsquo;t letters or numbers with underscores.<p>

    <p>For example, the chapter named &ldquo;Entities, Keys, and Properties&rdquo; has an ID of <code>Entities__Keys__and_Properties</code>.  Notice how both spaces and punctuation characters become underscores.  This section would be referred to in text with an <code>&lt;xref&gt;</code> element, like so:</p>

    <pre>For more information about keys, see &lt;xref linkend="Entities__Keys__and_Properties"/&gt;.</pre>

    <p>An ID must be unique across all IDs in the entire document.  If Scriv2DocBook finds multiple sections with the same title, it generates IDs by appending a number at the end of the ID, where the number is sequential in the order the sections appear in the document.  For example, if each of your chapters ends with a section entitled &ldquo;Exercises,&rdquo; the ID of the first section is <code>Exercises</code>, the second is <code>Exerises_1</code>, the third is <code>Exercises_2</code>, and so on.</p>

    <p>It is an XML validation error if an <code>&lt;xref&gt;</code>&rsquo;s <code>linkend</code> attribute refers to an element ID that doesn&rsquo;t exist in the document.  Scriv2DocBook reports such errors when it validates the output.  These errors can be difficult to troubleshoot.  You may wish to examine the generated output to confirm what ID Scriv2DocBook generated for a problematic section.</p>


    <h3 id="Block_Elements">Block Elements</h3>

    <p>As shown above, you add paragraphs in a section your Scrivener document by typing them directly, omitting the <code>&lt;para&gt;</code> tags and separating each paragraph with a blank line.  To add another kind of block element, such as a <code>&lt;table&gt;</code>, separate it from the preceding and following paragraphs with blank lines.</p>

    <pre>The &lt;code&gt;WHERE&lt;/code&gt; clause is equivalent to one or more
filters. It is not like SQL&rsquo;s &lt;code&gt;WHERE&lt;/code&gt; clause,
and does not support arbitrary logical expressions. In particular, it
does not support testing the logical-OR of two conditions.

The value on the righthand side of a condition can be a literal value
that appears inside the query string. Seven of the datastore value
types have string literal representations, as shown in &lt;xref
linkend="gql_value_literals"/&gt;.

&lt;table id="gql_value_literals"&gt;
  &lt;title&gt;GQL value literals for datastore types&lt;/title&gt;
  &lt;tgroup cols="3"&gt;
    &lt;colspec colname="c1"/&gt;
    &lt;colspec colname="c2"/&gt;
    &lt;colspec colname="c3"/&gt;
    &lt;thead&gt;
      &lt;row&gt;
        &lt;entry&gt;Type&lt;/entry&gt;
        &lt;entry&gt;Literal syntax&lt;/entry&gt;
        ...</pre>


    <h3 id="Block_Elements_Containing_Paragraphs">Block Elements Containing Paragraphs</h3>

    <p>Some block elements can (or must) contain paragraphs, such as <code>&lt;note&gt;</code> or <code>&lt;listitem&gt;</code>.  In these cases, you must type the <code>&lt;para&gt;</code> and <code>&lt;/para&gt;</code> tags, as in any other XML document.  Scriv2DocBook only adds <code>&lt;para&gt;</code> tags automatically for top-level paragraphs.</p>

<pre>&lt;note&gt;
  &lt;para&gt;Be sure to use the &lt;code&gt;logging&lt;/code&gt;
  level name (such as &lt;code&gt;FINEST&lt;/code&gt;) and not the App
  Engine level name for values in
  &lt;filename&gt;logging.properties&lt;/filename&gt;. App Engine log
  levels only affect how messages are represented in the Admin
  Console.&lt;/para&gt;
&lt;/note&gt;</pre>


    <h3 id="Other_Features_of_XML_and_DocBook">Other Features of XML and DocBook</h3>

    <p>Beyond sections and section-level paragraphs, your Scrivener project is simply DocBook XML.  Scriv2DocBook takes what you type into your project, and drops it directly into the XML document.  The result must be valid XML, and Scriv2DocBook checks that it is and reports errors.</p>

    <p>It&rsquo;s easy to forget that the text you type into your Scrivener project will be interpreted as XML, especially since your document omit structural tags and <code>&lt;para&gt;</code> tags.  In particular, you must remember that characters with special meaning to XML must be typed as XML entities, especially in regions such as code samples.  Watch for these three characters:</p>

<table>
  <tr>
    <td>left angle bracket (&ldquo;less than&rdquo;)</td>
    <td><code>&lt;</code></td>
    <td><code>&amp;lt;</code></td>
  </tr>
  <tr>
    <td>right angle bracket (&ldquo;greater than&rdquo;)</td>
    <td><code>&gt;</code></td>
    <td><code>&amp;gt;</code></td>
  </tr>
  <tr>
    <td>ampersand</td>
    <td><code>&amp;</code></td>
    <td><code>&amp;amp;</code></td>
  </tr>
</table>

    <p>Note that you must also use XML entities in section titles if you want them to appear as characters.  DocBook markup is typically not allowed in titles as a matter of style.</p>

    <p>Other features, such as elements containing preformatted text (<code>&lt;programlisting&gt;</code>) and XML Includes, are also supported.  Simply type them as they should appear in the final XML document into your Scrivener project.</p>


    <h2 id="Exporting_DocBook_XML">Exporting DocBook XML</h2>

    <p>Once you have a draft of your project that you want to export to DocBook, you use Scrivener&rsquo;s OPML export feature and the <code>s2d</code> tool to produce the DocBook XML.</p>

    <p>To export the Scriv2DocBook project as DocBook XML:</p>

    <ol>
      <li>
        <p>In Scrivener, select the chapters you wish to export.  You can do this in one of two ways:
          <ul>
            <li>Select each of the individual top-level sections to export, holding down the command key (Mac OS X) or control key (Windows) while clicking to select more than one.  Each section you select becomes a chapter in the result.</li>
            <li>Select the &ldquo;Draft&rdquo; section.  If the export contains only one section <emphasis>and</emphasis> it is named &ldquo;Draft,&rdquo; then each of the sections inside &ldquo;Draft&rdquo; becomes a chapter in the result.</li>
          </ul>
        </p>
      </li>
      <li>
        <p>Select the <strong>File</strong> menu, <strong>Export...</strong>, <strong>OPML File...</strong>.  In the dialog, select a location and enter a filename.  Select <strong>Titles and Text</strong>.  Make sure <strong>Export entire binder</strong> is not checked.  Click <strong>Export</strong>.</p>
      </li>
      <li>
        <p>At a command prompt (e.g. Mac OS X Terminal), run the <code>s2d</code> command with the exported OPML file, the path to the output directory, and the path to your DocBook schema files using the <code>--schema-dir</code> argument.  This might look something like this:</p>
        <pre>./scriv2docbook/s2d mybook.opml mybook --schema-dir=docbook-xml-4</pre>
        <p>Scriv2DocBook converts the project to DocBook XML files in the given directory (e.g. <code>mybook/</code>).  It also validates the XML.  If no XML errors are reported, then the XML is valid.</p>
      </li>
    </ol>

    <p>If you are exporting your project for the first time to an empty directory, be sure to edit the <code>book.xml</code> file to update the <code>&lt;title&gt;</code> tag with the actual title of your book.</p>

    <p>If you are writing for O&rsquo;Reilly, you can export your project directly into the SVN client directory containing the template files that O&rsquo;Reilly provided you for your book.  <code>s2d</code> preserves the elements of <code>book.xml</code> not related to the inclusion of chapters.</p>


    <h3 id="How_the_XML_is_Organized">How the XML is Organized</h3>

    <p>The exported XML project consists of multiple files: a <code>book.xml</code> file that represents the structure of the book, and one file for each chapter.  Chapter files are named with both a number and the chapter ID, to make it easier to trace XML validation errors back to the Scrivener project.</p>

    <p>Here are the files for my book:</p>
    <pre>book.xml
ch00_Preface.xml
ch01_Introducing_Google_App_Engine.xml
ch02_Creating_an_Application.xml
ch03_Handling_Web_Requests.xml
ch04_Datastore_Entities.xml
ch05_Datastore_Queries.xml
ch06_Datastore_Transactions.xml
ch07_Data_Modeling_with_Python.xml
ch08_The_Java_Persistence_API.xml
ch09_The_Memory_Cache.xml
ch10_Fetching_URLs_and_Web_Resources.xml
ch11_Sending_and_Receiving_Mail_and_Instant_Messages.xml
ch12_Bulk_Data_Operations_and_Remote_Access.xml
ch13_Task_Queues_and_Scheduled_Tasks.xml
ch14_The_Django_Web_Application_Framework.xml
ch15_Deploying_and_Managing_Applications.xml</pre>

    <p>The <code>book.xml</code> file contains the DocBook root element, the book <code>&lt;title&gt;</code> element, and XInclude directives that refer to the files for each chapter.  For example:</p>

<pre>&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"&gt;

&lt;book id="I_book_d1e1"&gt;
  &lt;title&gt;Programming Google App Engine&lt;/title&gt;
  &lt;xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="bookinfo.xml"/&gt;
  &lt;xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="dedication.xml"/&gt;
  &lt;xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ch00_Preface.xml"/&gt;
  &lt;xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ch01_Introducing_Google_App_Engine.xml"/&gt;
  &lt;xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ch02_Creating_an_Application.xml"/&gt;
  &lt;xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ch03_Handling_Web_Requests.xml"/&gt;
  &lt;!-- ... --&gt;
  &lt;index/&gt;
  &lt;xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="colo.xml"/&gt;
&lt;/book&gt;</pre>

    <p>If you export into a directory that already contains DocBook XML in this structure, <code>s2d</code> attempts to preserve the contents of <code>book.xml</code>, and merely replaces the lines related to the inclusion of chapters.  Any chapter file it finds that has the same sequence number and ID as a chapter being exported will be overwritten with the new text.  All other files are preserved.</p>

    <p>If <code>s2d</code> finds old chapter files using this naming convention but are no longer used by the project, it will not delete them.  Instead, it will display the commands you can run to delete the files.  If your output directory is an SVN client, it will display the SVN commands needed to do this.</p>


    <h2 id="Importing_a_DocBook_Project_to_Scrivener">Importing a DocBook Project to Scrivener</h2>

    <p>You can use the <code>d2s</code> tool to import a DocBook project into Scrivener.</p>

    <p><strong>Note:</strong> The current version of <code>d2s</code> doesn&rsquo;t use a real XML parser, so results may vary.  It supports the layout generated by <code>s2d</code> (a <code>book.xml</code> file with XInclude directives for each of the chapters), which is also the layout of the O&rsquo;Reilly project template.  It does not support XInclude elsewhere in the document.  The tool does support single-file DocBook XML data.  It supports <code>&lt;sect#&gt;</code> tags, but not nested <code>&lt;section&gt;</code> tags.</p>

    <p>To import a (conforming) DocBook project:</p>

    <ol>
      <li>
        <p>If necessary, create a new Scrivener project, making sure that it uses the configuration you set above (monospace fonts, etc.) for new topics.</p>
      </li>
      <li>
        <p>At a command prompt (e.g. Mac OS X Terminal), run the <code>d2s</code> command on your DocBook data to produce an OPML file.  This might look something like this:</p>
        <pre>./scriv2docbook/d2s mybook/book.xml mybook.opml</pre>
      </li>
      <li>
        <p>Locate the OPML file in your computer&rsquo;s file browser (e.g. Mac OS X Finder) and drag it to the Binder of your Scrivener project.  Before letting go, align the insertion indicator to where you want the new Scrivener sections to be created.  In a fresh project, this would be one level inside Draft.</p>
      </li>
      <li>
        <p>If prompted, confirm the Import Files dialog by clicking the &ldquo;Import&rdquo; button.  Scrivener creates the new sections.</p>
      </li>
      <li>
        <p>Save the project.</p>
      </li>
    </ol>


    <h2 id="License">License</h2>

    <p>Scriv2DocBook is copyright &copy; 2011 Dan Sanderson.</p>

    <p>Licensed under the Apache License, Version 2.0 (the &ldquo;License&rdquo;); you may not use this file except in compliance with the License.  You may obtain a copy of the License at</p>

    <p><a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a></p>

    <p>Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an &ldquo;AS IS&rdquo; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</p>

  </div></body>
</html>
